home *** CD-ROM | disk | FTP | other *** search
- Path: eql.caltech.edu!rankin
- From: rankin@eql.caltech.edu (Pat Rankin)
- Newsgroups: comp.lang.c
- Subject: Re: Problem calling LIB$FIND_FILE on VAX
- Date: 19 Jan 1996 14:02 PST
- Organization: California Institute of Technology
- Distribution: world
- Message-ID: <19JAN199614022139@eql.caltech.edu>
- References: <1996Jan18.135459.1@vax.sbu.ac.uk>
- NNTP-Posting-Host: bear.eql.caltech.edu
- News-Software: VAX/VMS VNEWS 1.41x8
-
- In article <1996Jan18.135459.1@vax.sbu.ac.uk>, tonyh@vax.sbu.ac.uk writes...
- > I'm having difficulty trying to call the lib$find_file(,,,,,,) VAX
- > Run-Time-Library (RTL) command from within a C program. I think my
- > problem is not with the parameters of the actual lib$ call itself,
- > but with the "$descriptor" part that actually holds the values, I've
- > been through the VAX manuals and the "descriptor" part is still unclear
- > to me. Am I accessing it correctly?...
-
- This topic would be more appropriate in comp.os.vms.
-
- >%SYSTEM-F-ACCVIO, access violation, reason mask=01, virtual address=010E0102,
- [...]
-
- That virtual "address" looks like the value of the first 32 bits of
- one of your string descriptors.
-
- [...]
- > struct dsc$descriptor_s FileFound;
- [...]
- > /* Call library function Lib$find_file(,,,,) */
- > status = lib$find_file( descriptor( FName ), FileFound,
- > ContexVar, 0, 0, 0, 1 );
-
- You are passing `FileFound' by value but lib$find_file expects to
- receive it by reference. You need to use `&FileFound' to pass a pointer
- to your variable. `ContexVar' and those integer constants also have
- the same problem. (Actually worse; you're using unadorned 0 where you
- ought to be using null pointers, and clearly there's no prototype in
- scope or the `FileFound' mismatch would have been caught by the compiler.)
- lib$XXX routines take arguments by reference so that they're relatively
- straightforward to use with any programming language; C code needs to
- construct pointers rather than pass immediate values.
-
- > if (status == SS$_NORMAL) {
- > FileFound.dsc$a_pointer[ FileFound.dsc$w_length ] = '\0';
- > }
-
- You should not be checking for an explicit value; check for an odd
- number, which is the most generic way to test VMS condition codes for
- success. And since `FileFound' defines a static string, lib$find_file
- will not touch its length field, so your '\0' would always end up being
- stored at `instr[255]' and not actually trim the resulting file name.
- All lib$XXX routines which write to static strings will pad their output
- values with trailing spaces to fill out the full length defined for the
- string. Since VMS file names never have trailing spaces in them, you
- can trim the string by starting at the end of the buffer and backing up
- until you hit any non-space character or the beginning of the buffer.
- Or you could switch to dynamic strings, but I'd advise against that.
- With dynamic allocation you would have the exact length, but there'd be
- no guarantee of room in the allocated buffer to append a trailing NUL
- byte for use as a normal C-style string.
-
- Pat Rankin, rankin@eql.caltech.edu
-